package com.soul.server.server;

import cn.hutool.core.util.PageUtil;
import com.github.tobato.fastdfs.domain.conn.FdfsWebServer;
import com.github.tobato.fastdfs.domain.fdfs.StorePath;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import com.soul.autoconfig.template.AliyunGreenTemplate;
import com.soul.autoconfig.template.OssTemplate;
import com.soul.commons.constans.Constants;
import com.soul.commons.exception.SoulGlobalException;
import com.soul.dubbo.api.db.UserInfoApi;
import com.soul.dubbo.api.mongo.SmallVideoApi;
import com.soul.model.db.UserInfo;
import com.soul.model.mongo.Video;
import com.soul.model.vo.ErrorResult;
import com.soul.model.vo.PageResult;
import com.soul.model.vo.VideoVo;
import com.soul.server.utils.UserHolder;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author mdoya
 * @version 1.0
 * @description:
 */
@Slf4j
@Service
public class SmallVideoService {

    @DubboReference
    private SmallVideoApi smallVideoApi;

    @Autowired
    private OssTemplate ossTemplate;

    @Autowired
    private FastFileStorageClient fastFileStorageClient;

    @Autowired
    private FdfsWebServer fdfsWebServer;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @DubboReference
    private UserInfoApi userInfoApi;

    @Autowired
    private MqMessageService mqMessageService;

    /**
     *  视频 - 视频上传
     * @param videoThumbnail 封面视频
     * @param videoFile 视频文件
     * @return
     */
//    @CacheEvict(value="videos",allEntries = true)  //清空缓存
    public void addSmallVideos(MultipartFile videoThumbnail, MultipartFile videoFile) {
        try {
            // 1. 保存封面
            Long currendUserId = UserHolder.getUserId();
            String ossUrl = ossTemplate.upload(videoThumbnail.getOriginalFilename(), videoThumbnail.getInputStream());
            String suffix = videoFile.getOriginalFilename().substring(videoFile.getOriginalFilename().lastIndexOf(".") + 1);
            // 2. 保存视频  参数1：视频字节流  参数2：视频字节 参数3：后缀 参数4：用不到
            StorePath storePath = fastFileStorageClient.uploadFile(videoFile.getInputStream(), videoFile.getSize(), suffix, null);
            // 3. 视频路径拼接
            String videolPath = fdfsWebServer.getWebServerUrl() +storePath.getFullPath();
            // 4. 构造video对象
            Video video = new Video();
            video.setVideoUrl(videolPath);
            video.setPicUrl(ossUrl);
            video.setText("开心哟");
            video.setUserId(currendUserId);
            video.setId(ObjectId.get());
            // 5. 调用服务保存
            smallVideoApi.addVideo(video);
            // 6. 将视频记录写入日志队列-视频推荐队列中
            mqMessageService.sendLogMessage(currendUserId,"0301","video",video.getId().toHexString());
        } catch (IOException e) {
            log.error("上传视频失败: {}",e.getMessage());
            throw new SoulGlobalException(ErrorResult.error());
        }

    }

    /**
     *  查询小视频分页列表
     * @param page 码数
     * @param pagesize 每天条数
     * @return List<VideoVo>
     */
    // 查询视频列表
   /* @Cacheable(
            value="videos",
            key = "T(com.soul.server.utils.UserHolder).getUserId()+'_'+#page+'_'+#pagesize")*/
    public PageResult<VideoVo> findPageSmallVideos(Long page, Long pagesize) {
        Long currendUserId = UserHolder.getUserId();
        // 1. redis中大数据推荐小视频
        String key = Constants.VIDEOS_RECOMMEND + currendUserId;
        String redisVideoids = stringRedisTemplate.opsForValue().get(key); // id与id之间用逗号隔开
        Long counts = 0L; // 总条数
        Integer pages = 0; // 总页码

        // 2. 大数据推荐小视频
        PageResult<Video> videoPageResult = new PageResult<>();

        if (StringUtils.isNotEmpty(redisVideoids)){
            String[] videoIds = redisVideoids.split(",");
            counts = Long.valueOf(videoIds.length);
            List<Long> videoIdsList = Arrays.stream(videoIds).skip((page - 1) * pagesize).limit(pagesize).map(Long::valueOf).collect(Collectors.toList());
            videoPageResult = smallVideoApi.findByIdsAndCondition(videoIdsList,page,pagesize);
            counts = videoPageResult.getCounts(); // 总条数
            pages = PageUtil.totalPage(counts.intValue(),videoPageResult.getPagesize().intValue()); // 总页码
            videoPageResult.setPages(Long.valueOf(pages)); // 总页码
        } else { // 3. MongoDB最新小视频
            videoPageResult = smallVideoApi.findByIdsAndCondition(null,page,pagesize);
            counts = videoPageResult.getCounts(); // 总条数
        }

        List<VideoVo> videoVoList = new ArrayList<>();
        List<Video> videoList = videoPageResult.getItems();
        // 4. 较空
        if (CollectionUtils.isEmpty(videoList)){
            return null;
        }
        // 5. video视频找到对应用户详细
        List<Long> videoUserIds = videoList.stream().map(Video::getUserId).collect(Collectors.toList());
        Map<Long, UserInfo> userInfoMap = userInfoApi.findIdsUserInfoList(videoUserIds);
        // 6. 构建vo并且返回
        for (Video video : videoList) {
            videoVoList.add(VideoVo.init(userInfoMap.get(video.getUserId()),video));
        }
        return new PageResult<>(page,pagesize,counts,videoVoList);
    }

    /**
     *  视频点赞
     * @param likeId
     * @return
     */
    public Integer like(String likeId) {
        return null;
    }

    /**
     *  视频点赞 - 取消
     * @param likeId
     * @return
     */
    public Integer dislike(String likeId) {
        return null;
    }

    /**
     *  视频用户关注
     * @param uid
     * @return
     */
    public Integer userFocus(String uid) {
        return null;
    }

    /**
     *  视频用户关注 - 取消
     * @param uid
     * @return
     */
    public Integer userUnFocus(String uid) {
        return null;
    }

    /**
     *  视频 - 评论列表
     * @param id
     * @return
     */
    public Integer comments(String id) {
        return null;
    }
}
